/**
 * Copyright@xiaocong.tv 2012
 */
package cn.uncode.baas.server.filter;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;

import cn.uncode.baas.server.constant.Resource;
import cn.uncode.baas.server.utils.PropertiesUtil;



/**
 * @author weijun.ye
 * @version
 * @date 2012-3-31
 */
public class ResourceFilter implements Filter {
	
	private boolean domainCross = false;
	
	private List<String> excludesPattern;

    /*
     * @see javax.servlet.Filter#destroy()
     */
    public void destroy() {
        // ignore
    }

    /*
     * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest,
     * javax.servlet.ServletResponse, javax.servlet.FilterChain)
     */
    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException,
            ServletException {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) resp;
        
        if(domainCross){
        	response.addHeader("Access-Control-Allow-Origin", "*");
            response.addHeader("Access-Control-Allow-Methods", "POST,GET,PUT,DELETE,OPTIONS");
            response.addHeader("Access-Control-Allow-Credentials", "true");
            response.addHeader("Access-Control-Allow-Headers", "Content-Type,X-Requested-With,token");
            response.addHeader("Access-Control-Max-Age", "600000");
        }

        // jsonp
        if (Resource.REQ_METHOD_GET.equals(request.getMethod()) && !isExclude(request.getRequestURI())) {
            String callBack = request.getParameter(Resource.RESP_CALLBACK);
            if (StringUtils.isNotEmpty(callBack)) {
                ResourceResponseWrapper wapper = new ResourceResponseWrapper(response);
                chain.doFilter(req, wapper);
                byte[] json = wapper.getResponseData();
                StringBuffer jsonStr = new StringBuffer(new String(json, "UTF-8"));
                jsonStr.insert(0, callBack + "(");
                jsonStr.append(")");
                ServletOutputStream output = response.getOutputStream();
                output.write(jsonStr.toString().getBytes("UTF-8"));
                output.flush();
            } else {
                chain.doFilter(req, response);
            }
        } else {
            chain.doFilter(req, response);
        }

    }

    /*
     * @see javax.servlet.Filter#init(javax.servlet.FilterConfig)
     */
    public void init(FilterConfig cf) throws ServletException {
    	Map<String, String> properties = PropertiesUtil.loadPropertiesToMap();
        if(null != properties && properties.containsKey("filter.domain.cross")){
        	Object value = properties.get("filter.domain.cross");
        	if(null != value){
        		domainCross = Boolean.valueOf(String.valueOf(value));
        	}
        }
        if(null != properties && properties.containsKey("filter.excludes")){
        	Object value = properties.get("filter.excludes");
        	if(null != value){
        		String excludeStr = String.valueOf(value);
        		if(excludeStr.trim().length() > 0){
        			excludesPattern = Arrays.asList(excludeStr.split("\\s*,\\s*"));
        		}
        	}
        }
        if(null == excludesPattern){
        	excludesPattern = new ArrayList<String>();
        }
    }
    
    private boolean isExclude(String uri){
    	if(StringUtils.isNotEmpty(uri)){
    		String type = uri.substring(uri.lastIndexOf(".") + 1);
        	for(String ex : excludesPattern){
        		if(ex.endsWith(type)){
        			return true;
        		}
        	}
    	}
    	return false;
    }

}
